<template>
    <a-form-model class="ag-form" ref="form" v-bind="formAttrs">
        <a-row v-bind="rowAttrs">
            <a-col v-for="(item,i) in columns" :key="item.key+'-'+i" v-bind="itemAttrs[i].col">
                <slot :name="item.prop" v-if="item.slotCol"></slot>
                <a-form-model-item v-else v-bind="itemAttrs[i].item">
                    <slot v-if="item.slot" :name="item.prop"></slot>
                    <component :is="item.is||'a-input'" v-model="data[item.prop]" v-on="item.on" v-bind="itemAttrs[i].component">
                    </component>
                </a-form-model-item>
            </a-col>
        </a-row>
    </a-form-model>
</template>

<script>
const ItemKeys = [
    "label",
    "prop",
    "autoLink",
    "colon",
    "extra",
    "help",
    "hasFeedback",
    "htmlFor",
    "labelCol",
    "wrapperCol",
    "labelAlign",
    "required",
    "validateStatus"
];
const formKeys = [
    "hideRequiredMark",
    "labelAlign",
    "layout",
    "labelCol",
    "wrapperCol",
    "colon",
    "validateOnRuleChange"
];
const customItemKey = ["is", "slot", "slotCol", "on", "col", "row"];
const customFormKey = ["col", "row"];

export default {
    name: "AgForm",
    components: {},
    props: {
        data: {
            type: Object,
            default: () => new Object()
        },
        config: {
            type: Object,
            default: () => new Object()
        },
        columns: {
            type: Array,
            default: () => new Array()
        }
    },
    data () {
        return {};
    },
    computed: {
        formAttrs () {
            const layout = this.config.layout || "horizontal";
            const labelCol = this.config.labelCol || { span: 8 };
            const wrapperCol = this.config.wrapperCol || { span: 16 };
            const attrs = {
                layout,
                model: this.data,
                rules: {},
                labelCol: layout == "horizontal" ? labelCol : {},
                wrapperCol: layout == "horizontal" ? wrapperCol : {}
            };
            this.columns.forEach(v => {
                v.rules && (attrs.rules[v.prop] = v.rules);
            });
            for (const key in this.config) {
                if (formKeys.includes(key)) attrs[key] = this.config[key];
            }
            return attrs;
        },
        itemAttrs () {
            return this.columns.map(item => {
                const col = Object.assign({ span: 6 }, item.col || {});
                const attrs = {
                    item: {},
                    component: {},
                    col: this.formAttrs.layout == "horizontal" ? col : {}
                };
                for (const key in item) {
                    let a = !customItemKey.includes(key);
                    let b = ItemKeys.includes(key);
                    if (a && b) attrs.item[key] = item[key];
                    if (a && !b) attrs.component[key] = item[key];
                }
                return attrs;
            });
        },
        rowAttrs () {
            const attrs = { align: "middle", type: "flex" };
            return this.formAttrs.layout == "horizontal"
                ? Object.assign(attrs, this.config.row || {})
                : {};
        }
    },
    created () {
        this.initConfig();
    },
    methods: {
        initConfig () {
            this.config.validate = callback => {
                this.$refs.form.validate(callback);
            };
            this.config.resetFields = () => {
                this.$refs.form.resetFields();
            };
            this.config.clearValidate = props => {
                this.$refs.form.clearValidate(props);
            };
        }
    }
};
</script>
<style lang="scss" >
    .ant-form {
        .ag-form {
            label {
                margin-bottom: 0px;
                padding-left: 10px;
            }
        }

        .ant-form-item {
            margin-bottom: 10px;
        }
        .ant-calendar-picker {
            width: 100%;
        }
    }

    .ag-form.ant-form-vertical {
        .ant-form-item {
            padding-bottom: 0px;
        }
    }

    .ag-form.ant-form-inline {
        .ant-select {
            width: 177px;
        }
        .ant-col {
            display: inline-block;
            margin-right: 5px;
            margin-bottom: 0;
        }
    }
</style>